Code First notes



If you get foriegn key contstraint errors when you use the convention of int 'TableNameId' in a class (in these cases if you do not submit a key id the Entity framework will try and put in a 0) just put ? after the int (int?) to tell the EF to allow nulls.



DBContext


You need to build a DbContext class along with your OO classes.

public class TempRxContext : DbContext
 
 {
 
 
 
 // You can add custom code to this file. Changes will not be overwritten.
 
 //
 
 // If you want Entity Framework to drop and regenerate your database
 
 // automatically whenever you change your model schema, add the following
 
 // code to the Application_Start method in your Global.asax file.
 
 // Note: this will destroy and re-create your database with every model change.
 
 //
 
 //System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<ContosoUniversity.Models.ContosoUniversityContext>());
 
 
 
 public DbSet<Address> Addresses { get; set; }
 
 
 
 
 
}

Check out this page in {0} translated from {1}translated fromOriginal:Translated:Automatic translation powered by Microsoft® TranslatorStart translatingStop translatingCloseClose and show original pageSelect

NOTE:
When the EF rebuilds your database remember to change your dates to date2s


You can force the creation of specifcs in your table with a map class


class

WorkHistoryMap : EntityTypeConfiguration<WorkHistory>

(example)
public WorkHistoryMap()
{
ToTable("WorkHistory");
HasKey(x => x.id);
Property(x => x.Name)
.HasColumnType("varchar")
.HasMaxLength(256)
.IsRequired();
HasRequired(x => x.User);
}
}

What to do if you get a null reference exception running Udate-Databse etc.

Uninstall - Microsoft Visual Studio 2010 ADO.NET Entity Framework Tools



For McvScaffolding


Make sure the your VS has the latest
MvcScaffolding by running

in NUGET

Install the scaffolding package.

Update-Package MvcScaffolding or
Install-Package MvcScaffolding

Good Blog post on using MvcScaffolding

http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/



For Code first with data migrations


http://blogs.msdn.com/b/adonet/archive/2011/09/06/code-first-migrations-alpha-2-walkthrough.aspx

to get started get the latest version of the EF

In NuGet
Install-Package EntityFramework -IncludePrerelease

You may have to get the latest Nu-Get
You may have to restart after this command

Then in Nu-Get run
Enable-Migrations
This will create a folder in your project called migrations and a class called Configuration.cs. I this class you can put data for your tables that needs to be persisted during migrations.

NOTE: EACH TIME YOU RUN THIS IT REBUILDS YOUR CONFIGURATIONS.CS
Eg.

context.PharmacyExperiences.AddOrUpdate(
p => p.experience,
new PharmacyExperience { experience = "Retail" },
new PharmacyExperience { experience = "Hospital" });


You can then run:
Add-Migration MyFirstMigration <-- whatever name you want

This will build a class for your tables in the migrations folder

Finally you run :

Update-Database

This will build out the database and add the seed data.
based on the connection string in your web.config

Note: this means we comment out the line in Global.asax.cs
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TempRxContext>());

Troubleshooting
if you get 'you cannot call a method on a null-valued expression' when tryin to run the nuget commands, then restart VS

If you set
AutomaticMigrationsEnabled =true;
in the Configuration consctructor then you can run Update-Database repeatedly.

Notes :

Remember after every migration to set all datatimes to datetime2

1. I have run into situations where in order to get the data to seed, you need to run Update-Database twice.
2. I have run into situations where I have had to comment out data migrations until the database has been created correctly due to the datetime2 problem.
3. I have even had to delete the db and run a dummy migration without the seed to get the db to build properly
4. If update failes due to contraints or indexes, delete the offender and rerun



MANY TO MANY DATA RELATIONSHIPS IN CODE FIRST / EF


To have the EF build many to many relationship tables put a list of objects in each of the objects that have the many to many relationship

EG.

public class PharmacyExperience
{
[Key]public int id { get; set; }
public string experience { get; set; }
public virtual ICollection<ContratorProfile> contratorProfiles { get; set; } <---
}

public class ContratorProfile
{
[Key]publicint id { get; set; }
public bool felony { get; set; }
public bool citizen { get; set; }
public bool workStatus { get; set; }
public virtual ICollection<License> licenses { get; set; }
public virtual ICollection<WorkHistory> workHistorys { get; set; }
public virtual ICollection<PharmacyExperience> PharmacyExperiences { get; set; }<---
public virtual ICollection<LevelOfEducation> LevelOfEducations { get; set; }
public virtual ICollection<PlacementPreference> PlacementPreferences { get; set; }
}

Will give you (among other things) a table called

PharmacyExperienceContratorProfiles




Good blog
In order to change the objects to correctly create the associations in the db schema and to get the *many-valued* associations working... like those objects that must maintain collections or lists of other objects.

On this page, scroll down just a bit to the section header "Code First And Associations" to see links to the Association tutorials. I think this blog is pretty easy to understand compared to many I've seen!

http://weblogs.asp.net/manavi/archive/2011/03/27/associations-in-ef-4-1-code-first-part-1-introduction-and-basic-concepts.aspx



Foriegn key relationships


Foriegn key relationships you need to define the object relationships in you classes with a virtual

eg.

public virtual Contractor contractor { get; set; }

otherwise the objects will appear as null when you 'get' and object from the db.

you can also use
[ForeignKey("Customer")]
public string CustomerID {get;set;}
as a decorator




Scaffolding in MVC3


There are new capabilities for scaffolding in MVC3

Using NUGet

Install-Package MvcScaffolding

Get the capabilities:

Get-DefaultScaffolder

Generate the Controller and Views and the DBContext object from a class
Scaffold Controller Categories <-- categories is a class

Note: If you want the scaffolder to automagically build out your drop downs then add the attribute to your class for the foriegn key as well as the list .

eg.
public int PositionId { get; set; } <-- this references the 'id' column in the Positions table
public virtual Position position { get; set; } <-- this builds the foriegn key in the host table



Notes on attributes that can be added to your Classes in the Model to be formatted in the scaffolder.

This attribute formats output
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]

This attribute will cause atext area to be built.
[DataType(DataType.MultilineText)]

[ScaffoldColumn(false)] works for standard MVC scaffolding but not for NuGet scaffolding

-------------------------------------------------

Default Values

You can add default values in the constructor of the class
eg.

public class Job
 
 {
 
 
 
 public Job()
 
 {
 
 this.datePosted = DateTime.Now;
 
 }
This will translate into a constraint on the table like :

USE [TempRxTest]
 
GO
 
 
 
ALTER TABLE [dbo].[Jobs] ADD CONSTRAINT [DF_Jobs_datePosted] DEFAULT (getdate()) FOR [datePosted]
 
GO
 
 



To handle the 'There is already an open DataReader'


This might happen when you scaffold a complex page .

To fix add this to you connection string.

MultipleActiveResultSets = true